﻿#include "EditorNodePositionPropertyView.h"

#include "Widgets/EditorDragableSpinWidget.h"
#include "Widgets/TextWidget.h"
#include "Widgets/Positioners/VerticalPositionerWidget.h"
#include "Widgets/RectangleWidget.h"

#include "Framework/Editor.h"
#include "Theme/EditorTheme.h"

void REditorNodePositionPropertyView::BindViewModel(TSharedObjectPtr<REditorPropertyViewModel> InViewModel)
{
    Super::BindViewModel(InViewModel);
    NodePositionViewModel =  InViewModel;
}

void REditorNodePositionPropertyView::CreateWidget(TSharedObjectPtr<RVerticalPositionerWidget> InPropertyList)
{
    auto Root=NewWidget<RWidget>(InPropertyList);
    Root->Anchor.HorizontalFill(InPropertyList);
    RWidgetWeakPtr RootWeak=Root;
    Root->Height=[this](){
        if(NodePositionViewModel->bThreeLine)
        {
            return NodePositionViewModel->LineHeight*3;
        }
        else
        {
            return NodePositionViewModel->LineHeight;
        }
    };    

    auto NameLabel=NewWidget<RTextWidget>(Root);
    NameLabel->Width= [this](){
        return NodePositionViewModel->GetSpliterLeftOffset();
    };
    NameLabel->Text=U"位置";
    NameLabel->VerticalAlignment=ETextVerticalAlignment::Center;

    auto Spliter=NewWidget<RRectangleWidget>(Root);
    Spliter->Width=NodePositionViewModel->SpliterWidth;
    Spliter->X=NodePositionViewModel->GetSpliterLeftOffset();
    Spliter->Anchor.VerticalFill(Root);
    Spliter->FillColor=REditor::Get()->CurrentTheme->SpliterColor;

    auto ValueContainer=NewWidget<RWidget>(Root);
    ValueContainer->Anchor.LeftReference=Spliter;
    ValueContainer->Anchor.LeftReferenceEdge=EHorizontalWidgetEdge::Right;
    ValueContainer->Anchor.RightReference=Root;

    RWidgetWeakPtr ValueContainerWeak=ValueContainer;
    ValueContainer->Height=[this,ValueContainerWeak](){
        const float OneValueWidth=
            NodePositionViewModel->LabelWidth
            +NodePositionViewModel->ValueWidth;
        if(ValueContainerWeak->PresentSize.X>(OneValueWidth*3))
        {
            //put 3 values in one line
            NodePositionViewModel->bThreeLine=false;
            return NodePositionViewModel->LineHeight;
        }
        else
        {
            //put 1 value in one line
            NodePositionViewModel->bThreeLine=true;
            return NodePositionViewModel->LineHeight*3;
        }
    };
    
    auto OneLine=NewWidget<RWidget>(ValueContainer);
    OneLine->Anchor.Fill(ValueContainer);
    OneLine->Visible=[this](){
        return !NodePositionViewModel->bThreeLine;
    };
    auto ThreeLine=NewWidget<RWidget>(ValueContainer);
    ThreeLine->Anchor.Fill(ValueContainer);
    ThreeLine->Visible=[this](){
        return NodePositionViewModel->bThreeLine;
    };

    const float Step=0.1f;
    auto XLabel=NewWidget<RTextWidget>(OneLine);
    XLabel->Width=NodePositionViewModel->LabelWidth;
    XLabel->Text=U"X";
    XLabel->Anchor.LeftReference=OneLine;
    XLabel->Anchor.VerticalCenterReference=OneLine;

    auto XValue=NewWidget<REditorDragableSpinWidget>(OneLine);
    XValue->Width=NodePositionViewModel->ValueWidth;
    XValue->Anchor.LeftReference=XLabel;
    XValue->Anchor.LeftReferenceEdge= EHorizontalWidgetEdge::Right;
    XValue->Anchor.VerticalCenterReference=OneLine;
    XValue->Value=[this](){
        return NodePositionViewModel->GetX();
    };
    XValue->OnAccepted.BindLambda([this](ETextEditStopReason,float InValue){
        NodePositionViewModel->SetX(InValue);
    });
    XValue->Step=Step;

    auto YLabel=NewWidget<RTextWidget>(OneLine);
    YLabel->Width=NodePositionViewModel->LabelWidth;
    YLabel->Text=U"Y";
    YLabel->Anchor.LeftReference=XValue;
    YLabel->Anchor.LeftReferenceEdge= EHorizontalWidgetEdge::Right;
    YLabel->Anchor.VerticalCenterReference=OneLine;

    auto YValue=NewWidget<REditorDragableSpinWidget>(OneLine);
    YValue->Width=NodePositionViewModel->ValueWidth;
    YValue->Anchor.LeftReference=YLabel;
    YValue->Anchor.LeftReferenceEdge= EHorizontalWidgetEdge::Right;
    YValue->Anchor.VerticalCenterReference=OneLine;
    YValue->Value=[this](){
        return NodePositionViewModel->GetY();
    };
    YValue->OnAccepted.BindLambda([this](ETextEditStopReason,float InValue){
        NodePositionViewModel->SetY(InValue);
    });
    YValue->Step=Step;

    auto ZLabel=NewWidget<RTextWidget>(OneLine);
    ZLabel->Width=NodePositionViewModel->LabelWidth;
    ZLabel->Text=U"Z";
    ZLabel->Anchor.LeftReference=YValue;
    ZLabel->Anchor.LeftReferenceEdge= EHorizontalWidgetEdge::Right;
    ZLabel->Anchor.VerticalCenterReference=OneLine;

    auto ZValue=NewWidget<REditorDragableSpinWidget>(OneLine);
    ZValue->Width=NodePositionViewModel->ValueWidth;
    ZValue->Anchor.LeftReference=ZLabel;
    ZValue->Anchor.LeftReferenceEdge= EHorizontalWidgetEdge::Right;
    ZValue->Anchor.VerticalCenterReference=OneLine;
    ZValue->Value=[this](){
        return NodePositionViewModel->GetZ();
    };
    ZValue->OnAccepted.BindLambda([this](ETextEditStopReason,float InValue){
        NodePositionViewModel->SetZ(InValue);
    });
    ZValue->Step=Step;


    auto XLabel3=NewWidget<RTextWidget>(ThreeLine);
    XLabel3->Width=NodePositionViewModel->LabelWidth;
    XLabel3->Text=U"X";
    XLabel3->Anchor.LeftReference=ThreeLine;
    XLabel3->Y=0;
    XLabel3->Height=NodePositionViewModel->LineHeight;

    auto XValue3=NewWidget<REditorDragableSpinWidget>(ThreeLine);
    XValue3->Width=NodePositionViewModel->ValueWidth;
    XValue3->Anchor.LeftReference=XLabel3;
    XValue3->Anchor.LeftReferenceEdge= EHorizontalWidgetEdge::Right;
    XValue3->Y=0;
    XValue3->Height=NodePositionViewModel->LineHeight;
    XValue3->Value=[this](){
        return NodePositionViewModel->GetX();
    };
    XValue3->OnAccepted.BindLambda([this](ETextEditStopReason,float InValue){
        NodePositionViewModel->SetX(InValue);
    });
    XValue3->Step=Step;

    auto YLabel3=NewWidget<RTextWidget>(ThreeLine);
    YLabel3->Width=NodePositionViewModel->LabelWidth;
    YLabel3->Text=U"Y";
    YLabel3->Anchor.LeftReference=ThreeLine;
    YLabel3->Y=NodePositionViewModel->LineHeight;
    YLabel3->Height=NodePositionViewModel->LineHeight;

    auto YValue3=NewWidget<REditorDragableSpinWidget>(ThreeLine);
    YValue3->Width=NodePositionViewModel->ValueWidth;
    YValue3->Anchor.LeftReference=YLabel3;
    YValue3->Anchor.LeftReferenceEdge= EHorizontalWidgetEdge::Right;
    YValue3->Y=NodePositionViewModel->LineHeight;
    YValue3->Height=NodePositionViewModel->LineHeight;
    YValue3->Value=[this](){
        return NodePositionViewModel->GetY();
    };
    YValue3->OnAccepted.BindLambda([this](ETextEditStopReason,float InValue){
        NodePositionViewModel->SetY(InValue);
    });
    YValue3->Step=Step;

    auto ZLabel3=NewWidget<RTextWidget>(ThreeLine);
    ZLabel3->Width=NodePositionViewModel->LabelWidth;
    ZLabel3->Text=U"Z";
    ZLabel3->Anchor.LeftReference=ThreeLine;
    ZLabel3->Y=NodePositionViewModel->LineHeight*2;
    ZLabel3->Height=NodePositionViewModel->LineHeight;

    auto ZValue3=NewWidget<REditorDragableSpinWidget>(ThreeLine);
    ZValue3->Width=NodePositionViewModel->ValueWidth;
    ZValue3->Anchor.LeftReference=ZLabel3;
    ZValue3->Anchor.LeftReferenceEdge= EHorizontalWidgetEdge::Right;
    ZValue3->Y=NodePositionViewModel->LineHeight*2;
    ZValue3->Height=NodePositionViewModel->LineHeight;
    ZValue3->Value=[this](){
        return NodePositionViewModel->GetZ();
    };
    ZValue3->OnAccepted.BindLambda([this](ETextEditStopReason,float InValue){
        NodePositionViewModel->SetZ(InValue);
    });
    ZValue3->Step=Step;

}
